#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <crypto/hash.h>
#include "tls_fs.h"
#include "tls_x509.h"
#include "tls_rsa.h"

#define SERVER_CERT_PATH "/home/zzhwaxy/Desktop/rsa_sign_ko/rsa_server.crt"
#define SERVER_KEY_PATH "/home/zzhwaxy/Desktop/rsa_sign_ko/rsa_server.key"

int sha512(char *plaintext, int psize, u8 *output)
{
    struct crypto_shash *tfm;
    struct shash_desc *shash;
    int ret;

    tfm = crypto_alloc_shash("sha512", 0, 0);
    if (IS_ERR(tfm)) {
        printk("crypto_alloc_ahash failed: err %ld", PTR_ERR(tfm));
        return PTR_ERR(tfm);
    }

    shash = kzalloc(sizeof(*shash) + crypto_shash_descsize(tfm),
                    GFP_KERNEL);
    if (!shash) {
        ret = -ENOMEM;
    goto failed;
    }

    shash->tfm = tfm;

    ret = crypto_shash_digest(shash, plaintext, psize, output);

    kfree(shash);

failed:
    crypto_free_shash(tfm);
    return ret;
}

static int __init x509_parser_init(void)
{
    char keyshare[32];
    char sig[512];
    char *peer_pub_key;
    pr_info("Loading X.509 parser module\n");
    void *key = NULL;
    key = kzalloc(4096, GFP_KERNEL);
    int keylen = kread_key(key, SERVER_KEY_PATH);
    if (keylen < 0) {
        pr_info("read key failed \n");
    } else {
        pr_info("keylen:%d\n", keylen);
    }
    memset(keyshare, 0x1, sizeof(char) * 32);
    memset(sig, 0x0, sizeof(char) * 512);
    if (key != NULL) {
        pkcs1pad_sign(key, keyshare, 32, sig, 512);
    }

    //   --------------------------------------------- verify
    void *cert = NULL;
    cert = kzalloc(4096, GFP_KERNEL);
    peer_pub_key = kzalloc(1024, GFP_KERNEL);
    int certlen = kread_cert(cert, SERVER_CERT_PATH);
    printk("cert len : %d \n", certlen);
    int res = kcert_parse(cert, peer_pub_key, certlen);
    printk("kcert_parse result: %d \n", res);
    pkcs1pad_verify(peer_pub_key, sig, 512, keyshare, 32);
    return 0;
}

static void __exit x509_parser_exit(void)
{
    pr_info("Unloading X.509 parser module\n");
}

module_init(x509_parser_init);
module_exit(x509_parser_exit);

MODULE_LICENSE("GPL");
